#include "xaudio_play.h"
#include <SDL.h>
#include <iostream>
class CXAudioPlay : public XAudioPlay {
public:
  CXAudioPlay() : XAudioPlay() {}
  bool Open(XAudioSpec &spec) override {
    spec_ = spec;
    Close();
    SDL_AudioSpec sdl_spec;
    sdl_spec.freq = spec.freq;
    sdl_spec.format = spec.format;
    sdl_spec.channels = spec.channels;
    sdl_spec.samples = spec.samples;
    sdl_spec.silence = 0;
    sdl_spec.userdata = this;
    sdl_spec.callback = &CXAudioPlay::AudioCallback;
    if (SDL_OpenAudio(&sdl_spec, nullptr) != 0) {
      std::cout << SDL_GetError() << std::endl;
    }
    SDL_PauseAudio(0);
    return true;
  }

  void Callback(unsigned char *stream, int len) override {
    SDL_memset(stream, 0, len);
    std::unique_lock<std::mutex> lock(mux_);
    if (audio_datas_.empty())
      return;
    //  1 buf大于stream缓冲 offset记录位置
    //  2 buf小于stream缓冲 拼接
    int mixde_size = 0;  // 已经处理的字节数
    int need_size = len; // 需要处理的字节数
    while (mixde_size < len) {
      if (audio_datas_.empty())
        break;
      auto &buf = audio_datas_.front();
      int size = buf.data.size() - buf.offset; // 剩余未处理的数据
      //  1 大于stream缓冲 offset记录位置
      if (size > need_size) {
        size = need_size;
      }
      SDL_MixAudio(stream + mixde_size, buf.data.data() + buf.offset, size,
                   volume_);
      buf.offset += size;
      need_size -= size;
      mixde_size += size;
      // 如果已经使用完来了，那么弹出
      if (buf.offset >= buf.data.size()) {
        audio_datas_.pop_front();
      }
    }
  }

  void Close() override {
    // 退出上一次打开的音频(先退出线程）
    SDL_QuitSubSystem(SDL_INIT_AUDIO);
    std::unique_lock<std::mutex> lock(mux_);
    audio_datas_.clear();
  }
};

XAudioPlay *XAudioPlay::Instance() {
  static CXAudioPlay play;
  return &play;
}

XAudioPlay::XAudioPlay() { SDL_Init(SDL_INIT_AUDIO); }
